package router

import (
	"github.com/gin-gonic/gin"
	"github.com/jmoiron/sqlx"
	"HeadLineNews/pkg/db/store"
	"HeadLineNews/pkg/snow"
	"HeadLineNews/utils/transaction"
	"log"
	"strings"
)

// 权限信息
type aPerm struct {
	permId   string
	permUrl  string
	permName string
}

// 初始不为空指针
var permSL = make([]*aPerm, 0)

type Router struct {
	*gin.RouterGroup
}

func newRouter(rg *gin.RouterGroup) *Router {
	return &Router{rg}
}

func (r *Router) Group(relativePath string, handlers ...gin.HandlerFunc) *Router {
	return &Router{r.RouterGroup.Group(relativePath, handlers...)}
}
func (r *Router) GET(relativePath, pathName string, handlers ...gin.HandlerFunc) {
	appendPerm(r.BasePath()+relativePath, pathName)
	r.RouterGroup.GET(relativePath, handlers...)
}
func (r *Router) POST(relativePath, pathName string, handlers ...gin.HandlerFunc) {
	appendPerm(r.BasePath()+relativePath, pathName)
	r.RouterGroup.POST(relativePath, handlers...)
}
func (r *Router) PUT(relativePath, pathName string, handlers ...gin.HandlerFunc) {
	appendPerm(r.BasePath()+relativePath, pathName)
	r.RouterGroup.PUT(relativePath, handlers...)
}
func (r *Router) DELETE(relativePath, pathName string, handlers ...gin.HandlerFunc) {
	appendPerm(r.BasePath()+relativePath, pathName)
	r.RouterGroup.DELETE(relativePath, handlers...)
}

// 添加权限，保证权限名称一致
func appendPerm(path, pathName string) {
	for _, perm := range permSL {
		if pathName == perm.permName {
			log.Fatalf("unique path name: %s", pathName)
		}
	}
	if !strings.Contains(path, "admin") {
		return
	}
	permSL = append(permSL, &aPerm{snow.GetID(), path, pathName})
}

// storeRouter 将权限存入数据库，做权限控制
func storeRouter() (err error) {
	if err = transaction.Transaction(store.DB(), func(tx *sqlx.Tx) (te error) {
		sqlStr := `DELETE FROM manage__permission`
		if _, te = tx.Exec(sqlStr); te != nil {
			log.Printf("clear perm table failed. error: %v", te)
			return
		}
		sqlStr = `INSERT INTO manage__permission(perm_id, perm_url, perm_comment, create_time) VALUES (?,?,?,NOW())`
		for _, perm := range permSL {
			if _, te = tx.Exec(sqlStr, perm.permId, perm.permUrl, perm.permName); te != nil {
				log.Printf("store perm failed. err: %v, path: %s, pathName: %s", te, perm.permUrl, perm.permName)
				return
			}
		}
		return
	}); err != nil {
		return
	}
	return
}
